﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArch.Utils;
using HYRevitCode.RevitDimensionUtility;

namespace YJKArch.DimensionModule
{
	internal class DimPublicFunc
	{
		public static XYZ To2d(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}

		public static XYZ SetPointZ(XYZ pt, double z)
		{
			return new XYZ(pt.X, pt.Y, z);
		}

		public static bool IsParallel(XYZ vt1, XYZ vt2)
		{
			double num = vt1.AngleTo(vt2);
			return num < DimPublicFunc.precision || Math.Abs(num - Math.PI) < DimPublicFunc.precision;
		}

		public static bool IsVertical(XYZ vt1, XYZ vt2)
		{
			return Math.Abs(vt1.AngleTo(vt2) - Math.PI*.5) < DimPublicFunc.precision;
		}

		public static Result PickPoint(UIDocument UIDoc, string statusPrompt, ref XYZ pt)
		{
			try
			{
				pt = UIDoc.Selection.PickPoint(statusPrompt);
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public static void SortPoint(ref XYZ pt1, ref XYZ pt2)
		{
			if (Math.Abs(pt1.X - pt2.X) > DimPublicFunc.precision)
			{
				if (pt1.X > pt2.X)
				{
					XYZ xyz = pt1;
					pt1 = pt2;
					pt2 = xyz;
					return;
				}
			}
			else if (pt1.Y > pt2.Y)
			{
				XYZ xyz2 = pt1;
				pt1 = pt2;
				pt2 = xyz2;
			}
		}

		public static bool TwoLineOnOne(XYZ ptS1, XYZ ptE1, XYZ ptS2, XYZ ptE2)
		{
			return Geometry.CalculateFootPoint(ptS1, ptE1, ptS2).DistanceTo(ptS2) <= DimPublicFunc.precision && Geometry.CalculateFootPoint(ptS1, ptE1, ptE2).DistanceTo(ptE2) <= DimPublicFunc.precision;
		}

		public static bool ExtendLine(XYZ ptExtend, ref XYZ ptStart, ref XYZ ptEnd)
		{
			if (Geometry.CalculateFootPoint(ptStart, ptEnd, ptExtend).DistanceTo(ptExtend) > DimPublicFunc.precision)
			{
				return false;
			}
			if (ptExtend.DistanceTo(ptStart) < DimPublicFunc.precision)
			{
				return false;
			}
			if (ptExtend.DistanceTo(ptEnd) < DimPublicFunc.precision)
			{
				return false;
			}
			double num = ptStart.DistanceTo(ptEnd);
			double num2 = ptExtend.DistanceTo(ptStart);
			double num3 = ptExtend.DistanceTo(ptEnd);
			if (Math.Abs(num - (num2 + num3)) < DimPublicFunc.precision)
			{
				return false;
			}
			if (ptExtend.DistanceTo(ptStart) < ptExtend.DistanceTo(ptEnd))
			{
				ptStart = ptExtend;
			}
			else
			{
				ptEnd = ptExtend;
			}
			return true;
		}

		public static Line ExtendLine(Line oldLine, int nExtendPos, double dExtendLen)
		{
			XYZ xyz = oldLine.GetEndPoint(0);
			XYZ xyz2 = oldLine.GetEndPoint(1);
			XYZ xyz3 = (xyz2 - xyz).Normalize();
			if (nExtendPos == 0)
			{
				xyz -= xyz3 * dExtendLen;
			}
			else if (nExtendPos == 1)
			{
				xyz2 += xyz3 * dExtendLen;
			}
			else if (nExtendPos == 2)
			{
				xyz -= xyz3 * dExtendLen;
				xyz2 += xyz3 * dExtendLen;
			}
			return YJKLineEx.YJKGetBound(xyz, xyz2);
		}

		public static Curve ChangeCurveElevation(Curve curve, double elevation)
		{
			if (curve.GetType() == typeof(Line))
			{
				return DimPublicFunc.ChangeLineElevation(curve as Line, elevation);
			}
			if (curve.GetType() == typeof(Arc))
			{
				return DimPublicFunc.ChangeArcElevation(curve as Arc, elevation);
			}
			return null;
		}

		public static Line ChangeLineElevation(Line line, double elevation)
		{
			XYZ xyz = line.GetEndPoint(0);
			XYZ xyz2 = line.GetEndPoint(1);
			xyz = new XYZ(xyz.X, xyz.Y, elevation);
			xyz2 = new XYZ(xyz2.X, xyz2.Y, elevation);
			return Line.CreateBound(xyz, xyz2);
		}

		public static Arc ChangeArcElevation(Arc arc, double elevation)
		{
			XYZ xyz = arc.GetEndPoint(0);
			XYZ xyz2 = arc.GetEndPoint(1);
			XYZ xyz3 = Geometry.CalculatMidPoint(xyz, xyz2, arc.Center, arc.Normal);
			xyz = new XYZ(xyz.X, xyz.Y, elevation);
			xyz2 = new XYZ(xyz2.X, xyz2.Y, elevation);
			xyz3 = new XYZ(xyz3.X, xyz3.Y, elevation);
			return Arc.Create(xyz, xyz2, xyz3);
		}

		public static void WallsConnectOneLine(Wall startWall, int nLinkEnd, bool bSameWidth, List<Wall> lstAllWall, ref List<Wall> lstResult)
		{
			LocationCurve locationCurve = startWall.Location as LocationCurve;
			if (locationCurve.Curve.GetType() != typeof(Line))
			{
				return;
			}
			XYZ hyendPoint = locationCurve.Curve.GetEndPoint(0);
			XYZ hyendPoint2 = locationCurve.Curve.GetEndPoint(1);
			XYZ xyz = (nLinkEnd == 0) ? hyendPoint : hyendPoint2;
			foreach (Wall wall in lstAllWall)
			{
				if (wall.Id.IntegerValue != startWall.Id.IntegerValue)
				{
					LocationCurve locationCurve2 = wall.Location as LocationCurve;
					if (!(locationCurve2.Curve.GetType() != typeof(Line)) && (!bSameWidth || Math.Abs(startWall.Width - wall.Width) <= DimPublicFunc.precision))
					{
						XYZ hyendPoint3 = locationCurve2.Curve.GetEndPoint(0);
						XYZ hyendPoint4 = locationCurve2.Curve.GetEndPoint(1);
						if (DimPublicFunc.TwoLineOnOne(hyendPoint, hyendPoint2, hyendPoint3, hyendPoint4))
						{
							if (hyendPoint3.DistanceTo(xyz) < DimPublicFunc.precision)
							{
								if (lstAllWall.Contains(wall))
								{
									lstAllWall.Remove(wall);
								}
								lstResult.Add(wall);
								DimPublicFunc.WallsConnectOneLine(wall, 1, bSameWidth, lstAllWall, ref lstResult);
								break;
							}
							if (hyendPoint4.DistanceTo(xyz) < DimPublicFunc.precision)
							{
								if (lstAllWall.Contains(wall))
								{
									lstAllWall.Remove(wall);
								}
								lstResult.Add(wall);
								DimPublicFunc.WallsConnectOneLine(wall, 0, bSameWidth, lstAllWall, ref lstResult);
								break;
							}
						}
					}
				}
			}
		}

		public static bool GetWallsEndPoint(List<Wall> lstWall, ref XYZ ptLeft, ref XYZ ptRight)
		{
			Wall wall = lstWall[0];
			ptLeft = WallAssistFunc.GetStartPt(wall);
			ptRight = WallAssistFunc.GetEndPt(wall);
			for (int i = 1; i < lstWall.Count; i++)
			{
				wall = lstWall[i];
				XYZ startPt = WallAssistFunc.GetStartPt(wall);
				XYZ endPt = WallAssistFunc.GetEndPt(wall);
				DimPublicFunc.ExtendLine(startPt, ref ptLeft, ref ptRight);
				DimPublicFunc.ExtendLine(endPt, ref ptLeft, ref ptRight);
			}
			return true;
		}

		public static void GetElementDimRef(UIApplication uiApp, Element elem, Line crossLine, ref List<ReferenceInfo> arDimRefInfo)
		{
			foreach (object obj in ElementAssistFunc.GetElementFaces(uiApp, uiApp.ActiveUIDocument.Document, elem))
			{
				Face face = (Face)obj;
				PlanarFace planarFace = face as PlanarFace;
				if (!(null == planarFace) && DimPublicFunc.IsParallel(planarFace.FaceNormal(), crossLine.Direction))
				{
					XYZ pt = Geometry.CalculateFootPoint(crossLine, planarFace.Origin);
					ReferenceInfo referenceInfo = new ReferenceInfo(face.Reference, DimPublicFunc.To2d(pt));
					if (!DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo))
					{
						arDimRefInfo.Add(referenceInfo);
					}
				}
			}
		}

		public static void GetGridDimRef(UIApplication uiApp, Grid grid, Line crossLine, ref List<ReferenceInfo> arDimRefInfo)
		{
			Options options = uiApp.Application.Create.NewGeometryOptions();
			options.ComputeReferences = true;
			options.IncludeNonVisibleObjects = false;
			options.View = uiApp.ActiveUIDocument.Document.ActiveView;
			GridType elem = uiApp.ActiveUIDocument.Document.GetElement(grid.GetTypeId()) as GridType;
			int num = elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).AsInteger();
			if (num != 0)
			{
				elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(0);
				uiApp.ActiveUIDocument.Document.Regenerate();
			}
			GeometryElement geometryElement = grid.get_Geometry(options);
			if (geometryElement == null)
			{
				return;
			}
			foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(geometryElement))
			{
				if (geometryObject is Curve)
				{
					Curve curve = geometryObject as Curve;
					if (curve.Reference != null)
					{
						XYZ hyendPoint = curve.GetEndPoint(0);
						XYZ xyz = Geometry.IntersectWithTwoCurves(DimPublicFunc.ChangeLineElevation(crossLine, hyendPoint.Z), curve, hyendPoint, true, false, uiApp.Application);
						if (xyz != null)
						{
							ReferenceInfo referenceInfo = new ReferenceInfo(curve.Reference, DimPublicFunc.To2d(xyz));
							if (!DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo))
							{
								arDimRefInfo.Add(referenceInfo);
								break;
							}
						}
					}
				}
			}
			if (num != 0)
			{
				elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(num);
			}
		}

		public static void GetWallDimRef(UIApplication uiApp, Wall wall, Line crossLine, bool bGetEndRef, ref List<ReferenceInfo> arDimRefInfo)
		{
			LocationCurve locationCurve = wall.Location as LocationCurve;
			XYZ hyendPoint = locationCurve.Curve.GetEndPoint(0);
			XYZ hyendPoint2 = locationCurve.Curve.GetEndPoint(1);
			List<ReferenceInfo> list = new List<ReferenceInfo>();
			if (wall.CurtainGrid != null)
			{
				DimPublicFunc.GetCurtainWall(uiApp, wall, crossLine, false, ref arDimRefInfo);
				return;
			}
			foreach (object obj in ElementAssistFunc.GetElementFaces(uiApp, uiApp.ActiveUIDocument.Document, wall))
			{
				Face face = (Face)obj;
				PlanarFace planarFace = face as PlanarFace;
				if (!(null == planarFace) && DimPublicFunc.IsParallel(planarFace.FaceNormal(), crossLine.Direction))
				{
					XYZ pt = Geometry.CalculateFootPoint(crossLine, planarFace.Origin);
					ReferenceInfo referenceInfo = new ReferenceInfo(face.Reference, DimPublicFunc.To2d(pt));
					if (!DimPublicFunc.HasExistRefInfo(list, referenceInfo))
					{
						list.Add(referenceInfo);
					}
				}
			}
			list.Sort(new DistanceComparer(DimPublicFunc.To2d(hyendPoint)));
			if (!bGetEndRef)
			{
				list.RemoveAt(0);
				list.RemoveAt(list.Count - 1);
			}
			else
			{
				if (DimPublicFunc.NearWallRef(uiApp, hyendPoint, crossLine, ref arDimRefInfo))
				{
					list.RemoveAt(0);
				}
				if (DimPublicFunc.NearWallRef(uiApp, hyendPoint2, crossLine, ref arDimRefInfo))
				{
					list.RemoveAt(list.Count - 1);
				}
			}
			foreach (ReferenceInfo referenceInfo2 in list)
			{
				if (!DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo2))
				{
					arDimRefInfo.Add(referenceInfo2);
				}
			}
		}

		public static XYZ CalcProjPointByPlane(XYZ ptTest, Plane planeProj)
		{
			return (Transform.CreateReflection(planeProj).OfPoint(ptTest) + ptTest) * 0.5;
		}

		public static Line CalcProjLineByPlane(Line line, Plane planeProj)
		{
			if (!line.IsBound)
			{
				return null;
			}
			XYZ xyz = DimPublicFunc.CalcProjPointByPlane(line.GetEndPoint(0), planeProj);
			XYZ xyz2 = DimPublicFunc.CalcProjPointByPlane(line.GetEndPoint(1), planeProj);
			try
			{
				return Line.CreateBound(xyz, xyz2);
			}
			catch
			{
			}
			return null;
		}

		public static List<Solid> GetAllSolid(GeometryElement inputValue, Transform useTransform = null, bool onlyGetStairsRun = false)
		{
			List<Solid> list = new List<Solid>();
			if (!(null == inputValue))
			{
				GeometryElement geometryElement = inputValue;
				if (useTransform != null)
				{
					geometryElement = geometryElement.GetTransformed(useTransform);
				}
				foreach (GeometryObject geometryObject in geometryElement)
				{
					if (!(null == geometryObject))
					{
						if (null != geometryObject as Solid && (geometryObject as Solid).Volume > 1E-06)
						{
							list.Add(geometryObject as Solid);
						}
						if (geometryObject is GeometryInstance && (!onlyGetStairsRun || (geometryObject as GeometryInstance).Symbol is StairsRun))
						{
							list.AddRange(DimPublicFunc.GetAllSolid((geometryObject as GeometryInstance).GetSymbolGeometry((geometryObject as GeometryInstance).Transform), null, false));
						}
					}
				}
			}
			return list;
		}

		private static List<Solid> GetMaxVolumeSolid(List<Solid> solids)
		{
			List<Solid> list = new List<Solid>();
			double num = 0.0;
			foreach (Solid solid in solids)
			{
				if (solid.Volume > num)
				{
					num = solid.Volume;
				}
			}
			foreach (Solid solid2 in solids)
			{
				if (Math.Abs(solid2.Volume - num) < 1E-06)
				{
					list.Add(solid2);
				}
			}
			return list;
		}

		private static List<Line> GetAllGeometryObeject(List<Solid> solids, ref List<PlanarFace> planarFaces)
		{
			List<Line> list = new List<Line>();
			foreach (Solid solid in solids)
			{
				if (!(solid == null))
				{
					foreach (object obj in solid.Faces)
					{
						PlanarFace planarFace = obj as PlanarFace;
						if (!(null == planarFace))
						{
							planarFaces.Add(planarFace);
						}
					}
					foreach (object obj2 in solid.Edges)
					{
						Edge edge = obj2 as Edge;
						if (!(null == edge))
						{
							Line line = edge.AsCurve() as Line;
							if (!(line == null))
							{
								list.Add(line);
							}
						}
					}
				}
			}
			return list;
		}

		private static void GetReference(Autodesk.Revit.DB.Document doc, Autodesk.Revit.DB.View activeView, Wall wall, Line crossLine, XYZ point, ref List<ReferenceInfo> lstRefInfo)
		{
			XYZ xyz = Geometry.CalculateFootPoint(crossLine, point);
			XYZ xyz2 = xyz.Add(wall.Orientation * 0.8 / 304.8);
			Line line = Line.CreateBound(xyz, xyz2);
			ReferenceInfo item = new ReferenceInfo(new Reference(doc.Create.NewDetailCurve(activeView, line)), DimPublicFunc.To2d(xyz));
			lstRefInfo.Add(item);
		}

		private static void GetCurtainWall(UIApplication uiApp, Wall wall, Line crossLine, bool bGetEndRef, ref List<ReferenceInfo> arDimRefInfo)
		{
			Autodesk.Revit.DB.Document document = uiApp.ActiveUIDocument.Document;
			Autodesk.Revit.DB.View activeView = document.ActiveView;
			int scale = activeView.Scale;
			List<ReferenceInfo> list = new List<ReferenceInfo>();
			CurtainGrid curtainGrid = wall.CurtainGrid;
			Curve curve = (wall.Location as LocationCurve).Curve;
			XYZ endPoint = curve.GetEndPoint(0);
			XYZ endPoint2 = curve.GetEndPoint(1);
			DimPublicFunc.GetReference(document, activeView, wall, crossLine, endPoint, ref list);
			DimPublicFunc.GetReference(document, activeView, wall, crossLine, endPoint2, ref list);
			XYZ xyz = curve.GetEndPoint(1) - curve.GetEndPoint(0);
			IEnumerable<ElementId> mullionIds = curtainGrid.GetMullionIds();
			List<Mullion> list2 = new List<Mullion>();
			foreach (ElementId elementId in mullionIds)
			{
				Mullion mullion = document.GetElement(elementId) as Mullion;
				if (mullion != null && DimPublicFunc.IfTowLinesVertical(mullion.LocationCurve, curve))
				{
					list2.Add(mullion);
				}
			}
			if (list2.Count > 0)
			{
				using (List<Mullion>.Enumerator enumerator2 = list2.GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						Mullion mullion2 = enumerator2.Current;
						try
						{
							MullionType mullionType = mullion2.Symbol as MullionType;
							double num = mullionType.get_Parameter(BuiltInParameter.RECT_MULLION_WIDTH1).AsDouble();
							double num2 = mullionType.get_Parameter(BuiltInParameter.RECT_MULLION_WIDTH2).AsDouble();
							LocationPoint locationPoint = mullion2.Location as LocationPoint;
							XYZ point = (locationPoint.Point.Add(-xyz.Normalize() * num) + locationPoint.Point.Add(xyz.Normalize() * num2)) / 2.0;
							DimPublicFunc.GetReference(document, activeView, wall, crossLine, point, ref list);
						}
						catch (Exception)
						{
							LocationPoint locationPoint2 = mullion2.Location as LocationPoint;
							DimPublicFunc.GetReference(document, activeView, wall, crossLine, locationPoint2.Point, ref list);
						}
					}
					goto IL_23B;
				}
			}
			foreach (ElementId elementId2 in curtainGrid.GetVGridLineIds())
			{
				CurtainGridLine curtainGridLine = document.GetElement(elementId2) as CurtainGridLine;
				if (curtainGridLine != null)
				{
					Curve fullCurve = curtainGridLine.FullCurve;
					DimPublicFunc.GetReference(document, activeView, wall, crossLine, fullCurve.GetEndPoint(0), ref list);
				}
			}
			IL_23B:
			foreach (ElementId elementId3 in curtainGrid.GetPanelIds())
			{
				Panel panel = uiApp.ActiveUIDocument.Document.GetElement(elementId3) as Panel;
				if (panel != null && !("玻璃" == panel.Name))
				{
					List<Solid> allSolid = DimPublicFunc.GetAllSolid(panel.get_Geometry(new Options()), null, false);
					List<PlanarFace> list3 = new List<PlanarFace>();
					if (allSolid != null)
					{
						DimPublicFunc.GetAllGeometryObeject(DimPublicFunc.GetMaxVolumeSolid(allSolid), ref list3);
						foreach (PlanarFace planarFace in list3)
						{
							if (!DimPublicFunc.IsParallel(planarFace.FaceNormal(), crossLine.Direction))
							{
								DimPublicFunc.GetReference(document, activeView, wall, crossLine, planarFace.Origin, ref list);
							}
						}
					}
				}
			}
			foreach (ReferenceInfo referenceInfo in list)
			{
				if (!DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo))
				{
					arDimRefInfo.Add(referenceInfo);
				}
			}
		}

		private static bool IfTowLinesVertical(Curve one, Curve two)
		{
			XYZ xyz = one.GetEndPoint(1) - one.GetEndPoint(0);
			XYZ xyz2 = two.GetEndPoint(1) - two.GetEndPoint(0);
			return Math.Abs(xyz.DotProduct(xyz2)) < 0.001;
		}

		public static void GetWallThickRef(UIApplication uiApp, Wall wall, Line crossLine, ViewDetailLevel viewLevel, ref List<ReferenceInfo> arDimRefInfo)
		{
            if ((int)viewLevel == 1)
			{
				IEnumerator enumerator = ElementAssistFunc.GetElementFaces(uiApp, uiApp.ActiveUIDocument.Document, wall).GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						object obj = enumerator.Current;
						Face face = (Face)obj;
						PlanarFace planarFace = face as PlanarFace;
						if (!(null == planarFace) && DimPublicFunc.IsParallel(planarFace.FaceNormal(), crossLine.Direction))
						{
							XYZ pt = Geometry.CalculateFootPoint(crossLine, planarFace.Origin);
							ReferenceInfo referenceInfo = new ReferenceInfo(face.Reference, DimPublicFunc.To2d(pt));
							if (!DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo))
							{
								arDimRefInfo.Add(referenceInfo);
							}
						}
					}
					return;
				}
			}
			Line line = null;
			Line line2 = null;
			if (DimPublicFunc.GetWallStructLine(uiApp, wall, ref line, ref line2))
			{
				XYZ hyendPoint = crossLine.GetEndPoint(0);
				XYZ xyz = line.Project(hyendPoint).XYZPoint;
				XYZ xyz2 = line2.Project(hyendPoint).XYZPoint;
				if (xyz.Z < hyendPoint.Z)
				{
					xyz = DimPublicFunc.SetPointZ(xyz, hyendPoint.Z);
				}
				if (xyz2.Z < hyendPoint.Z)
				{
					xyz2 = DimPublicFunc.SetPointZ(xyz2, hyendPoint.Z);
				}
				XYZ direction = line.Direction;
				SketchPlane sketchPlane = uiApp.ActiveUIDocument.Document.ActiveView.SketchPlane;
				Line line3 = YJKLineEx.YJKGetBound(xyz, xyz + direction * 0.5);
				line3 = DimPublicFunc.CalcProjLineByPlane(line3, sketchPlane.GetPlane());
				if (line3 == null)
				{
					return;
				}
				ModelCurve modelCurve = uiApp.ActiveUIDocument.Document.Create.NewModelCurve(line3, sketchPlane);
				ReferenceInfo referenceInfo2 = new ReferenceInfo(modelCurve.GeometryCurve.Reference, DimPublicFunc.To2d(xyz));
				if (DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo2))
				{
					uiApp.ActiveUIDocument.Document.DeleteElement(modelCurve);
				}
				else
				{
					arDimRefInfo.Add(referenceInfo2);
				}
				Line line4 = YJKLineEx.YJKGetBound(xyz2, xyz2 + direction * 0.5);
				line4 = DimPublicFunc.CalcProjLineByPlane(line4, sketchPlane.GetPlane());
				if (line4 == null)
				{
					return;
				}
				ModelCurve modelCurve2 = uiApp.ActiveUIDocument.Document.Create.NewModelCurve(line4, sketchPlane);
				ReferenceInfo referenceInfo3 = new ReferenceInfo(modelCurve2.GeometryCurve.Reference, DimPublicFunc.To2d(xyz2));
				if (DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo3))
				{
					uiApp.ActiveUIDocument.Document.DeleteElement(modelCurve2);
					return;
				}
				arDimRefInfo.Add(referenceInfo3);
			}
		}

		public static bool GetWallStructLine(UIApplication uiApp, Wall wall, ref Line structLine1, ref Line structLine2)
		{
			Line line = (wall.Location as LocationCurve).Curve as Line;
			if (line == null)
			{
				return false;
			}
			double num = 0.0;
			double num2 = 0.0;
			CompoundStructure compoundStructure = (uiApp.ActiveUIDocument.Document.GetElementById(wall.GetTypeId()) as WallType).GetCompoundStructure();
			if (compoundStructure == null)
			{
				return false;
			}
			IList<CompoundStructureLayer> layers = compoundStructure.GetLayers();
			int firstCoreLayerIndex = compoundStructure.GetFirstCoreLayerIndex();
			int lastCoreLayerIndex = compoundStructure.GetLastCoreLayerIndex();
			for (int i = 0; i <= lastCoreLayerIndex; i++)
			{
				CompoundStructureLayer compoundStructureLayer = layers[i];
				if (i < firstCoreLayerIndex)
				{
					num += compoundStructureLayer.Width;
				}
				else
				{
					num2 += compoundStructureLayer.Width;
				}
			}
			Line line2 = Geometry.OffsetLine(line, wall.Width / 2.0);
			structLine1 = Geometry.OffsetLine(line2, -num);
			structLine2 = Geometry.OffsetLine(structLine1, -num2);
			return true;
		}

		public static bool NearWallRef(UIApplication uiApp, XYZ ptBase, Line crossLine, ref List<ReferenceInfo> arDimRefInfo)
		{
			Autodesk.Revit.DB.Document document = uiApp.ActiveUIDocument.Document;
			List<Wall> list = (from w in new FilteredElementCollector(document, document.ActiveView.Id).OfClass(typeof(Wall))
			select w as Wall).ToList<Wall>();
			if (list == null || list.Count < 1)
			{
				return false;
			}
			XYZ hyendPoint = crossLine.GetEndPoint(0);
			XYZ hyendPoint2 = crossLine.GetEndPoint(1);
			XYZ xyz = Geometry.CalculateFootPoint(hyendPoint, hyendPoint2, ptBase);
			(hyendPoint2 - hyendPoint).Normalize();
			foreach (Wall wall in list)
			{
				LocationCurve locationCurve = wall.Location as LocationCurve;
				if (!(locationCurve.Curve.GetType() != typeof(Line)))
				{
					Line line = locationCurve.Curve as Line;
					if (DimPublicFunc.IsVertical(crossLine.Direction, line.Direction))
					{
						line = DimPublicFunc.ChangeLineElevation(line, hyendPoint.Z);
						line = DimPublicFunc.ExtendLine(line, 2, wall.Width / 2.0);
						XYZ xyz2 = Geometry.IntersectWithTwoCurves(crossLine, line, hyendPoint, false, false, uiApp.Application);
						if (xyz2 != null && xyz2.DistanceTo(xyz) < DimPublicFunc.precision)
						{
							ReferenceInfo referenceInfo = new ReferenceInfo(DimPublicFunc.GetWallCenterReference(uiApp, wall), DimPublicFunc.To2d(xyz2));
							if (!DimPublicFunc.HasExistRefInfo(arDimRefInfo, referenceInfo))
							{
								arDimRefInfo.Add(referenceInfo);
							}
							return true;
						}
					}
				}
			}
			return false;
		}

		public static List<Grid> LineCrossGrids(UIApplication uiApp, XYZ pt1, XYZ pt2)
		{
			List<Grid> list = (from g in new FilteredElementCollector(uiApp.ActiveUIDocument.Document).OfClass(typeof(Grid))
			select g as Grid).ToList<Grid>();
			if (list == null || list.Count < 1)
			{
				return null;
			}
			List<Grid> list2 = new List<Grid>();
			Line curve = YJKLineEx.YJKGetBound(pt1, pt2);
			foreach (Grid grid in list)
			{
				if (!grid.IsHidden(uiApp.ActiveUIDocument.ActiveView))
				{
					Curve curve2 = DimPublicFunc.ChangeCurveElevation(grid.Curve, pt1.Z);
					if (!(curve2.GetType() != typeof(Line)) && Geometry.IntersectWithTwoCurves(curve, curve2, pt1, false, false, uiApp.Application) != null)
					{
						list2.Add(grid);
					}
				}
			}
			return list2;
		}

		public static List<Wall> LineCrossWalls(UIApplication uiApp, XYZ pt1, XYZ pt2)
		{
			List<Element> list = DimPublicFunc.ElementsAtBoundingBox(uiApp.ActiveUIDocument.Document, pt1, pt2, BuiltInCategory.OST_Walls);
			if (list == null)
			{
				return null;
			}
			List<Wall> list2 = new List<Wall>();
			foreach (Element element in list)
			{
				list2.Add(element as Wall);
			}
			DimPublicFunc.ClearSurfaceWall(ref list2);
			return DimPublicFunc.LineCrossWalls(uiApp, list2, pt1, pt2);
		}

		public static List<Wall> LineCrossWalls(UIApplication uiApp, List<Wall> lstWall, XYZ pt1, XYZ pt2)
		{
			List<Wall> list = new List<Wall>();
			Line curve = null;
			try
			{
				curve = YJKLineEx.YJKGetBound(pt1, pt2);
			}
			catch (Exception)
			{
				return list;
			}
			foreach (Wall wall in lstWall)
			{
				LocationCurve locationCurve = wall.Location as LocationCurve;
				if (!(locationCurve.Curve.GetType() != typeof(Line)))
				{
					Line line = locationCurve.Curve as Line;
					if (!DimPublicFunc.IsParallel(pt2 - pt1, line.Direction))
					{
						line = DimPublicFunc.ChangeLineElevation(line, pt1.Z);
						if (Geometry.IntersectWithTwoCurves(curve, line, pt1, false, false, uiApp.Application) != null)
						{
							list.Add(wall);
						}
					}
				}
			}
			return list;
		}

		public static List<Element> ElementsAtBoundingBox(Autodesk.Revit.DB.Document doc, XYZ pt1, XYZ pt2, BuiltInCategory elemType)
		{
			double elevation = doc.ActiveView.GenLevel.Elevation;
			XYZ xyz = new XYZ(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y), elevation + 0.001);
			XYZ xyz2 = new XYZ(Math.Max(pt1.X, pt2.X), Math.Max(pt1.Y, pt2.Y), elevation + 10.0);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(new Outline(xyz, xyz2));
			return new FilteredElementCollector(doc, doc.ActiveView.Id).OfCategory(elemType).WherePasses(boundingBoxIntersectsFilter).ToList<Element>();
		}

		public static List<Dimension> GetCurViewDims(UIApplication uiApp)
		{
			Autodesk.Revit.DB.Document document = uiApp.ActiveUIDocument.Document;
			return (from d in new FilteredElementCollector(document, document.ActiveView.Id).OfClass(typeof(Dimension))
			select d as Dimension).ToList<Dimension>();
		}

		public static Reference GetWallCenterReference(UIApplication uiApp, Wall wall)
		{
			LocationCurve locationCurve = wall.Location as LocationCurve;
			if (locationCurve.Curve.GetType() != typeof(Line))
			{
				return null;
			}
			Options options = uiApp.Application.Create.NewGeometryOptions();
			options.IncludeNonVisibleObjects = true;
			options.ComputeReferences = true;
			options.View = uiApp.ActiveUIDocument.Document.ActiveView;
			List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(wall.get_Geometry(options));
			Line line = locationCurve.Curve as Line;
			foreach (GeometryObject geometryObject in geometryObjectArray)
			{
				Line line2 = geometryObject as Line;
				if (!(line2 == null) && line2.IsBound && DimPublicFunc.IsParallel(line2.Direction, line.Direction) && Geometry.Is_Points_Collinear(DimPublicFunc.To2d(line2.GetEndPoint(0)), DimPublicFunc.To2d(line.GetEndPoint(0)), DimPublicFunc.To2d(line.GetEndPoint(1)), 1E-09) && line2.Reference != null)
				{
					return line2.Reference;
				}
			}
			return null;
		}

		public static bool HasExistRefInfo(List<ReferenceInfo> arRefInfo, ReferenceInfo newRefInfo)
		{
			foreach (ReferenceInfo referenceInfo in arRefInfo)
			{
				if (newRefInfo.ThePosition.DistanceTo(referenceInfo.ThePosition) < DimPublicFunc.precision)
				{
					return true;
				}
			}
			return false;
		}

		public static Dimension CreateLinearDim(Autodesk.Revit.DB.Document doc, ReferenceArray arDimRef, XYZ ptDim, XYZ vtDim, DimensionTypeEnum dimTypeEnum = DimensionTypeEnum.ScaleDimension)
		{
			XYZ xyz = Geometry.RotateTo(vtDim, Math.PI*.5, XYZ.BasisZ);
			Line line = YJKLineEx.YJKGetBound(ptDim, ptDim + xyz * 10.0);
			DimensionType dimensionType = RevitDimensionUtiltyMethod.GetDimensionType(doc, dimTypeEnum, null);
			Dimension dimension = doc.Create.NewDimension(doc.ActiveView, line, arDimRef);
			if (dimensionType != null)
			{
				dimension.DimensionType = dimensionType;
			}
			RevitDimensionExtension.ResetDimTextPos(dimension);
			return dimension;
		}

		public static Dimension CreateWallThickDim(Autodesk.Revit.DB.Document doc, ReferenceArray arDimRef, XYZ ptDim, XYZ vtDim)
		{
			XYZ xyz = Geometry.RotateTo(vtDim, Math.PI*.5, XYZ.BasisZ);
			Line line = YJKLineEx.YJKGetBound(ptDim, ptDim + xyz * 10.0);
			DimensionType dimensionType = RevitDimensionUtiltyMethod.GetDimensionType(doc, DimensionTypeEnum.ScaleDimension, null);
			Dimension dimension = doc.Create.NewDimension(doc.ActiveView, line, arDimRef);
			if (dimensionType != null)
			{
				dimension.DimensionType = dimensionType;
			}
			RevitDimensionExtension.ResetDimTextPos(dimension);
			return dimension;
		}

		public static Line GetLinearDimSizeLine(Dimension dim)
		{
			if (dim.Curve == null || dim.Curve.GetType() != typeof(Line))
			{
				return null;
			}
			Line line = dim.Curve as Line;
			DimensionSegmentArray segments = dim.Segments;
			XYZ xyz2;
			if (segments.Size < 2)
			{
				BoundingBoxXYZ boundingBoxXYZ = dim.get_BoundingBox(dim.Document.ActiveView);
				XYZ xyz = boundingBoxXYZ.Min + (boundingBoxXYZ.Max - boundingBoxXYZ.Min) / 2.0;
				xyz2 = line.Project(xyz).XYZPoint;
			}
			else
			{
				XYZ xyz3 = null;
				XYZ xyz4 = null;
				foreach (object obj in segments)
				{
					DimensionSegment dimensionSegment = (DimensionSegment)obj;
					if (xyz3 == null)
					{
						xyz3 = dimensionSegment.Origin;
					}
					else if (xyz4 == null)
					{
						xyz4 = dimensionSegment.Origin;
					}
					else
					{
						DimPublicFunc.ExtendLine(dimensionSegment.Origin, ref xyz3, ref xyz4);
					}
				}
				xyz2 = xyz3 + (xyz4 - xyz3) / 2.0;
			}
			double num = dim.GetParameter(BuiltInParameter.DIM_TOTAL_LENGTH).AsDouble();
			XYZ startPoint = xyz2 + line.Direction * num / 2.0;
			XYZ endPoint = xyz2 - line.Direction * num / 2.0;
			return YJKLineEx.YJKGetBound(startPoint, endPoint);
		}

		public static string GetDimFlag(Dimension dim)
		{
			Schema schema = Schema.Lookup(new Guid(DimPublicFunc.HYDimFlag));
			if (schema == null)
			{
				return null;
			}
			Entity entity = dim.GetEntity(schema);
			if (entity == null || entity.Schema == null)
			{
				return null;
			}
			Field field = schema.GetField("Flag");
			if (field == null)
			{
				return null;
			}
			return entity.Get<string>(field);
		}

		public static void SetDimFlag(Dimension dim, string sDimFlag)
		{
			Guid guid = new Guid(DimPublicFunc.HYDimFlag);
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
				schemaBuilder.SetSchemaName("DimFlag");
				schemaBuilder.AddSimpleField("Flag", typeof(string));
				schema = schemaBuilder.Finish();
			}
			Entity entity = new Entity(schema);
			Field field = schema.GetField("Flag");
			entity.Set<string>(field, sDimFlag);
			dim.SetEntity(entity);
		}

		public static ElementId GetDimWallId(Dimension dim)
		{
			Schema schema = Schema.Lookup(new Guid(DimPublicFunc.AttachWall));
			if (schema == null)
			{
				return null;
			}
			Entity entity = dim.GetEntity(schema);
			if (entity == null || entity.Schema == null)
			{
				return null;
			}
			Field field = schema.GetField("WallId");
			if (field == null)
			{
				return null;
			}
			return entity.Get<ElementId>(field);
		}

		public static void SetDimWallId(Dimension dim, ElementId wallId)
		{
			Guid guid = new Guid(DimPublicFunc.AttachWall);
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
				schemaBuilder.SetSchemaName("AttachWallId");
				schemaBuilder.AddSimpleField("WallId", typeof(ElementId));
				schema = schemaBuilder.Finish();
			}
			Entity entity = new Entity(schema);
			Field field = schema.GetField("WallId");
			entity.Set<ElementId>(field, wallId);
			dim.SetEntity(entity);
		}

		public static void ClearSurfaceWall(ref List<Wall> lstAllWall)
		{
			if (lstAllWall == null || lstAllWall.Count < 1)
			{
				return;
			}
			for (int i = 0; i < lstAllWall.Count; i++)
			{
				Wall wall = lstAllWall[i];
				XYZ startPt = WallAssistFunc.GetStartPt(wall);
				XYZ endPt = WallAssistFunc.GetEndPt(wall);
				for (int j = 0; j < lstAllWall.Count; j++)
				{
					Wall wall2 = lstAllWall[j];
					if (!(wall2.Id == wall.Id) && !(wall2.LevelId != wall.LevelId) && wall.Width - wall2.Width > DimPublicFunc.precision)
					{
						XYZ startPt2 = WallAssistFunc.GetStartPt(wall2);
						XYZ endPt2 = WallAssistFunc.GetEndPt(wall2);
						if (DimPublicFunc.IsParallel(endPt2 - startPt2, endPt - startPt))
						{
							XYZ xyz = Geometry.CalculateFootPoint(startPt, endPt, startPt2);
							XYZ pt = Geometry.CalculateFootPoint(startPt, endPt, endPt2);
							if (startPt2.DistanceTo(xyz) <= wall.Width && Geometry.Is_Point_OnSegment(startPt, endPt, xyz, 1E-09) && Geometry.Is_Point_OnSegment(startPt, endPt, pt, 1E-09))
							{
								lstAllWall.RemoveAt(j);
								j--;
							}
						}
					}
				}
			}
		}

		public static void DrawLine(UIDocument UIDoc, XYZ ptStart, XYZ ptEnd)
		{
			Line line = YJKLineEx.YJKGetBound(ptStart, ptEnd);
			DetailCurve detailCurve = UIDoc.Document.Create.NewDetailCurve(UIDoc.ActiveView, line);
			OverrideGraphicSettings overrideGraphicSettings = new OverrideGraphicSettings();
			overrideGraphicSettings.SetProjectionLineColor(new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0));
			UIDoc.Document.ActiveView.SetElementOverrides(detailCurve.Id, overrideGraphicSettings);
		}

		protected static double precision = 1E-05;

		protected static string HYDimFlag = "D6E04E06-CA94-4D17-8E64-94672192A65B";

		protected static string AttachWall = "B622FFDC-FBF3-43FE-9535-E24DB542A5AB";
	}
}
